/**
 * FileName: SqlTypeConverter
 * Author: Wb
 * Date: 2025/9/25 8:45
 * Description:
 * History:
 */
package org.test.device.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author Wb
 * @create 2025/9/25
 * @since 1.0.0
 */
@Slf4j
public class SqlTypeConverter {

    // 定义状态映射
    private static final Map<Integer, String> STATUS_MAP = Map.of(
            0, "正常",
            1, "删除"
    );

    private static final Map<Integer, String> DELETED_MAP = Map.of(
            0, "正常",
            1, "删除"
    );

    /**
     * 将entity对象的属性格式化为一个字符串
     *
     * @param entity 源对象
     * @param endEntity 目标对象
     * @param format 日期格式
     */
    public static void convertEntity(Object entity, Object endEntity, String format) {
        copyEntity(entity, endEntity);
        changeDateToString(entity, endEntity, format);
        changeDeletedToString(entity, endEntity);
    }

    /**
     * 将entity对象的属性复制到endEntity对象中
     *
     * @param entity 源对象
     * @param endEntity 目标对象
     */
    public static void copyEntity(Object entity, Object endEntity) {
        BeanUtils.copyProperties(entity, endEntity);
    }

    /**
     * 将entity对象的Date类型属性格式化为字符串
     *
     * @param entity 源对象
     * @param endEntity 目标对象
     * @param format 日期格式
     */
    private static void changeDateToString(Object entity, Object endEntity, String format) {
        log.info("SqlTypeConverter-changeDateToString:实体类属性转换！");
        if (entity == null || endEntity == null) {
            return;
        }
        try {
            // 获取所有字段（包括父类字段）
            List<Field> allFields = getAllFields(entity.getClass());

            for (Field entityField : allFields) {
                entityField.setAccessible(true);
                Object value = entityField.get(entity);
                if (value != null) {
                    // 处理日期类型字段
                    if (value instanceof Date) {
                        handleDateField(value, entityField, endEntity, format);
                    }

                    // 处理 status 字段
                    if ("status".equals(entityField.getName()) && value instanceof String) {
                        handleStatusField((String) value, endEntity);
                    }
                }
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new IllegalArgumentException("转换失败", e);
        }
    }

    /**
     * 将entity对象的Integer类型的deleted字段转换为String类型
     *
     * @param entity 源对象
     * @param endEntity 目标对象
     */
    private static void changeDeletedToString(Object entity, Object endEntity) {
        if (entity == null || endEntity == null) {
            return;
        }
        try {
            // 获取所有字段（包括父类字段）
            List<Field> allFields = getAllFields(entity.getClass());

            for (Field entityField : allFields) {
                entityField.setAccessible(true);
                Object value = entityField.get(entity);

                if (value != null && "deleted".equals(entityField.getName()) && value instanceof Integer) {
                    // 查找目标字段
                    Field endEntityField = endEntity.getClass().getDeclaredField("deleted");
                    endEntityField.setAccessible(true);

                    // 获取状态描述
                    String statusDescription = Optional.ofNullable(DELETED_MAP.get((Integer) value))
                            .orElse("未知状态");

                    endEntityField.set(endEntity, statusDescription);
                }
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new IllegalArgumentException("转换失败", e);
        }
    }

    /**
     * 获取类的所有字段（包括父类字段）
     *
     * @param clazz 类对象
     * @return 字段列表
     */
    private static List<Field> getAllFields(Class<?> clazz) {
        List<Field> fields = new ArrayList<>();
        while (clazz != null) {
            fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        return fields;
    }

    /**
     * 处理日期类型字段
     *
     * @param value 字段值
     * @param entityField 源字段
     * @param endEntity 目标对象
     * @param format 日期格式
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private static void handleDateField(Object value, Field entityField, Object endEntity, String format) throws NoSuchFieldException, IllegalAccessException {
        // 查找目标字段
        try {
            Field endEntityField = endEntity.getClass().getDeclaredField(entityField.getName());
            endEntityField.setAccessible(true);

            // 转换日期为字符串
            if (endEntityField.getType() == String.class) {
                Date dateValue = convertToDate(value);
                if (dateValue != null) {
                    SimpleDateFormat sdf = new SimpleDateFormat(format);
                    String formattedDate = sdf.format(dateValue);
                    endEntityField.set(endEntity, formattedDate);
                }
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    private static Date convertToDate(Object value) {
        if (value instanceof Date) {
            return (Date) value;
        } else if (value instanceof String) {
            try {
                // 尝试使用 ISO 8601 格式解析字符串
                SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
                return isoFormat.parse((String) value);
            } catch (ParseException e) {
                // 解析失败，返回 null
                return null;
            }
        }
        return null;
    }

    /**
     * 处理 status 字段
     *
     * @param status 状态值
     * @param endEntity 目标对象
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private static void handleStatusField(String status, Object endEntity) throws NoSuchFieldException, IllegalAccessException {
        // 查找目标字段
        Field endEntityField = endEntity.getClass().getDeclaredField("status");
        endEntityField.setAccessible(true);

        // 获取状态描述
        String statusDescription = Optional.ofNullable(STATUS_MAP.get(status))
                .orElse("未知状态");

        endEntityField.set(endEntity, statusDescription);
    }
}